將資料上傳至Firebase上
使用UIImagePikerController來選取照片上傳
// 產生一個UIImagePickerController的控制器
let imagePicker = UIImagePickerController()
// 先點ImageView屬性欄位的User Interaction Enabled
// 新增一個Tap Gesture Recognizer套用到ImageView上
// 將ViewController連結Tap Gesture Recognizer的動作上,將連結方式選擇為@IBAction
@IBAction func addimage(_ sender: UIGestureRecognizer){
let controller = UIAlertController(title: "選取上傳方式", message: nil, preferredStyle: .alert)
let controllerAction_camera = UIAlertAction(title: "相機", style: .default){(_ ) in
self.cameraTake()
}
let controllerAction_gallery = UIAlertAction(title: "相簿", style: .default, handler: {(_ ) in
self.galleryUse()})
let controllerAction_cancel = UIAlertAction(title: "取消", style: .cancel, handler: nil)
controller.addAction(controllerAction_camera)
controller.addAction(controllerAction_gallery)
controller.addAction(controllerAction_cancel)
self.present(controller, animated: true, completion: nil)
}
// 使用Function讓程式碼更加容易讀
func cameraTake(){
// 選擇ImagePickerController的類型
imagePicker.sourceType = .camera
self.present(imagePicker, animated: true, completion: nil)
}
func galleryUse(){
imagePicker.sourceType = .photoLibrary
self.present(imagePicker, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// 將imagePicker控制器的指派透過現在這個ViewController來執行
imagePicker.delegate = self
}
// UIImagePickerControllerDelegate讓資料知道會用哪種方式來儲存
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// 這邊選擇使用原相機儲存,且將圖片顯示在ImageView
if let image = info[.originalImage] as? UIImage {
self.addimage.image = image
}
picker.dismiss(animated: true)
}
打開Info.plist
按下+
輸入Privacy - Camera Usage Description
輸入Privacy - Photo Library Usage Description
為什麼輸入這個?
因為iOS的隱私設定,如果沒有這兩項說明沒有辦法啟動我的相機與相簿
安裝Firebase/Database
pod 'Firebase/Database'
pod install
新增文字資料到網路上
import FirebaseDatabase
// 新增一個add的按鈕,並連結到這個ViewController
@IBAction func addbutton(_ sender: Any) {
// 在Firebase上傳資料需要有一個refence(),故新增一個
let ref = Database.database().reference()
// child(" ")表示生成一個分支叫" "
// childByAutoId()表示會自動生成一個ID編碼
// setValue()是上傳的主要function
ref.child("BookName").childByAutoId().setValue(AddBookName.text)
ref.child("BookAuthor").childByAutoId().setValue(AddBookAuthor.text)
ref.child("BookISBN").childByAutoId().setValue(AddBookISBN.text)
ref.child("BookImage").childByAutoId().setValue(addimage.image)
}
成果展示:
補充:
後來發現如果使用AutoId我根本很難去提取資料,所以我要將我的書名命名
下面補上,後來做的修改
我希望我的資料是透過一個名為Book的Structure上傳到網路上
那麼我應該做出這樣的修改:
先新增一個Swift文件,名為Book
import Foundation
import Firebase
class Book{
var booktitle:String
var bookauthors:String
var bookISBN:String
var bookimage:[String]?
var key:String
var ref:DataBaseReference?
// 自己從程式內部輸入進資料
// 將外部(textfield)的這些輸入到Book這個Struture內變數
init(booktitle:String,bookauthors:String,bookISBN:String,bookimage:[String],key:String = ""){
self.key = key
self.booktitle = booktitle
self.bookauthors = bookauthors
self.bookISBN = bookISBN
self.bookimage = bookimage
self.ref = nil
}
// 當從網路上抓下來的檔案,輸入進資料
init(snapshot:DataSnapshot){
key = snapshot.key
let snapshotValue = snapshot.value as![String:AnyObject]
booktitle = snapshotValue["booktitle"] as! String
bookauthors = snapshotValue["bookauthors"] as! String
bookISBN = snapshotValue["bookISBN"] as! String
bookimage = snapshotValue["bookimage"] as? [String]
ref = snapshot.ref
}
// 因為上傳資料,需要將其變成字典的形式
// 所以將Book變成字典的形式
func becomeDictionary() -> Any{
return ["booktitle":booktitle,
"bookauthors":bookauthors,
"bookISBN":bookISBN,
"bookimage":bookimage
]
}
原本的addButton也會開始做很多事情
func addbutton(){
// 將剛剛資料輸入進Book struture
let book = Book(booktitle:AddBookName.text!,bookauthors:AddBookAuthors.text,
bookISBN:AddBookISBN.text,bookimage:[""])
// 將剛剛的資料上傳到Firebase
self.uploadtoFirebase(value:book)
}
func uploadtoFirebase(values:Book){
// 首先先用每個Book的名字創造一個類似資料夾的東西,來存放每本書的資料
let bookItemRef = self.ref!.child(values.booktitle.lowercased())
// 因為要上傳圖片,我們需要一個Storage的ref
// 一樣根據書名,做一個類似資料夾的東西
let storageImageRef = Storage.storage().reference().child("BookRentImage").child((values.booktitle))
// 當我們要上傳的時候,有鑒於上傳圖片跟上傳一些文字資料的速度並不一樣,所以在這邊先做一個辨認
// 如果有的話,則新增一個在書名的資料夾內
if addimage.image != nil{
let uploadTask = StorageImageRef.child("\(values.booktitle).jpeg").putData(self.ImageData!,metadata:nil,completion:{(data,error) in
if error != nil{
print("Error",error.localizedDescription)
return
}
})
DispatchQueue.global(qos:.userInitiated).async{
uploadTask.observe(.success,handler:{(snapshot) in
storageImageRef.child("\(values.booktitle).jpeg").downloadURL{(url,error) in
if let error = error{
print("Error",error.localizedDescription)
}else{
if let imageFileURL = url.absoluteString{
// 檢查是不是所上傳的URL
print("This is my imageURL",imageURL)
// 如果沒有問題,那麼將上傳圖片所產生的URL也一併上傳
let bookItem = Book(booktitle:values.booktitle,bookauthors:values.bookauthors,bookISBN:values.bookISBN,bookimage:imageURL)
bookItemRef.setValue(bookItem.becomeDictionary(),withCompletionBlock:{(error,ref) in
if error == nil{
print("Success")
}
// 如果要加上UIAlertController加在這邊
}
}
}
}
大功告成!
參考網址:
Swift & Firebase DB(Realtime&Cloud Firestore) 全解析
[APP開發-使用Swift] 21-2. Firebase - 新增